import os
import sys
import copy
import urllib
import urllib2
import cookielib
import json

COL_GSL = u'GSL'
COL_TOKEN = u'token'
COL_FAMILY = u'family'

def getGslDict(filename):
    Gsl = {}
    Token = {}
    f = open(filename)
    for line in f.readlines():
        word = line.strip().split()
        Gsl[word[2]] = int(word[0])
        Token[word[2]] = int(word[1])
    f.close()
    return Gsl, Token

def getFamilyDict(filename):
    Dict = {}
    f = open(filename)
    for line in f.readlines():
        family = line.strip().split('\t')
        family_id = family[1]
        family = family[2:]
        for word in family:
            Dict[word] = family_id
    f.close()
    return Dict
    
gslDict, tokenDict = getGslDict('input\\The General Service List.txt')
familyDict = getFamilyDict('input\\word_families.idx')

def getText(element, str=''):
    if element.nodeType == element.TEXT_NODE:
        return str+element.data.strip()
    elif element.nodeType == element.ELEMENT_NODE:
        for child in element.childNodes:
            str = getText(child, str)
        return str
    else:
        return str

def encodeStr(string):
    return unicode(string, 'utf-8')

reverseFlag = 1
def gslCompare(x, y):
    global reverseFlag
    if x == None and y !=None: return 1*reverseFlag
    elif x != None and y == None: return -1*reverseFlag
    else: return cmp(x,y)

def subConfigOutput(i, setConfig, words, title, COL_WORD, dumper, compare=gslCompare, key=lambda x:x[COL_GSL], reverse=False):
	wordsList = []
	if needDo(i, setConfig.get('group')):
		groupedWords = {}
		for word in words:
			group = word.get(setConfig['group']['key'])
			if groupedWords.get(group) == None:
			   groupedWords[group] = []
			groupedWords[group].append(word)
		for group in groupedWords.keys():
			tf = [setConfig['title'], group, title] if title else [setConfig['title'], group]
			wordsList += subSplitted(i, setConfig.get('split'), groupedWords[group], tf, COL_WORD, compare, key, reverse)
	else:
		tf = [setConfig['title'], title] if title else [setConfig['title']]
		wordsList += subSplitted(i, setConfig.get('split'), words, tf, COL_WORD, compare, key, reverse)
	for wordList in wordsList:
		dumpWords(' - '.join(wordList['title']), wordList['list'], dumper)

def sortWords(words, COL_WORD, compare=None, key=None, reverse=False):
    for i  in range(len(words)):
        word = words[i]
        headword = word.get(COL_WORD)
        word[COL_GSL] = gslDict.get(headword)
        word[COL_TOKEN] = tokenDict.get(headword)
        word[COL_FAMILY] = familyDict.get(headword)
        words[i] = word
    global reverseFlag
    reverseFlag = -1 if reverse else 1
    words.sort(compare, key, reverse)
    return words

def dumpWords(title, words, dumper):
    count = len(words)
    result = 'Skipped'
    if count : result = 'OK' if dumper.export(title, words) else 'Failed'
    print '%s : %s (%d) - %s' % (dumper.__class__.__name__, title, count, result)

def needDo(i, doConfig):
    if doConfig :
        doRange = doConfig.get('range') 
        if doRange :
            try:
                doRange.index(i)
                return True
            except ValueError:
                None
        else:
            return True
    return False

def splitWordsSet(factorRange, words):
    ratios = []
    all = len(words)
    for i in factorRange:
        mod = (all % i) if (all % i) else i
        ratios.append(1.0*mod/i)
    factor = factorRange[ratios.index(max(ratios))]
    decks = []
    deck = []
    for word in words:
        deck.append(word)
        if len(deck) ==  factor:
            decks.append(deck)
            deck = []
    if len(deck):decks.append(deck)
    return decks

def subSplitted(i, splitConfig, words, titleFactors, COL_WORD, compare=None, key=None, reverse=False):
    words = sortWords(words, COL_WORD, compare, key, reverse)
    wordsList=[]
    if needDo(i, splitConfig) :
        splitted = splitWordsSet(splitConfig['factor'], words)
        if len(splitted) == 1:
            wordsList.append({'title':titleFactors,'list':splitted[0]})
        else:
            for sub in range(len(splitted)):
                tf = copy.deepcopy(titleFactors)
                tf.append(encodeStr(str(sub+1)))
                wordsList.append({'title':tf,'list':splitted[sub]})
    else:
        wordsList.append({'title':titleFactors,'list':words})
    return wordsList

class FileDumper:
    folder = None
    def __init__(self, folder):
        self.folder = 'output\\'+ folder
        try:
            os.makedirs(self.folder)
        except Exception:
            None
    def export(self, title, words):
        keys = words[0].keys()
        keyLine = (u"\t".join(keys)) + u"\r\n"
        try:
            f = open(self.folder + '\\' + title+'.txt', 'wb')
            f.writelines(keyLine.encode('utf-8'))
            for word in words:
                line = u''
                for key in keys: line += unicode(word[key] if word[key] else '')+u"\t"
                line += u"\r\n"
                f.writelines(line.encode('utf-8'))
            f.close()
            return True
        except Exception:
            return False

class QuizletDumper:
    username = 'jueljust'
    password = 'password'
    loggined = False
    col_term = None
    col_def = None
    template = {
        'description' : '',
        'tags' : 'English, ESL, EFL, Vocabulary, Basic',
        'words_lang' : 'en',
        'defs_lang' : 'zh-TW'
    }
    def __init__(self, col_term=u'\u5b57\u8a5e', col_def=u'\u4e2d\u6587\u91cb\u7fa9', template=None):
        cj = cookielib.LWPCookieJar()
        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
        urllib2.install_opener(opener)
        self.login()
        self.col_term = col_term
        self.col_def = col_def
        if template:
            for k, v in template.items():
                self.template[k] = v
        
    def login(self):
        url = 'https://quizlet.com/login/'
        params = {}
        params['username'] = self.username
        params['password'] = self.password
        params['redir'] = 'http://quizlet.com/'
        params['rememberMe'] = 1
        postdata = urllib.urlencode(params)
        req = urllib2.Request(url, postdata)
        req.add_header( 'Cookie', 'fs=mcmv34')
        response = urllib2.urlopen(req)
        return response

    def delete(self, keywords):
        params = {'query':keywords}
        url = 'http://quizlet.com/feed/?seenSetIds=&' + urllib.urlencode(params)
        start = '<a class="set-link" href="'
        end = '">'
        count = 0
        response = urllib2.urlopen(url)
        if response.getcode() == 200 :
            content = response.read()
            content = json.JSONDecoder('utf-8').decode(content)
            content = content['content']
            while True :
                try:
                    content = content[content.index(start)+len(start):]
                    link = content[:content.index(end)]
                    set_id = link[1:link.index('/',1)]
                    count += 1
                    self.doDelete(set_id)
                except ValueError:
                    break
        return count

    def doDelete(self, set_id):
        url = '://quizlet.com/%s/delete/' % set_id
        postdata = 'qnonce='+self.getQnonce('http' + url)+'&do_delete=Yes%2C+Delete+this+Set'
        req = urllib2.Request('https' + url, postdata)
        req.add_header('Referer', 'http' + url)
        response = urllib2.urlopen(req)
        if response.getcode() == 200 :
            print 'delete %s' % set_id

    def getQnonce(self, url='http://quizlet.com/create_set/'):
        start = "<input name='qnonce' type='hidden' value='"
        end = "' />"
        response = urllib2.urlopen(url)
        if response.getcode() == 200 :
            content = response.read()
            content = unicode(content, 'utf-8')
            content = content[content.index(start)+len(start):]
            content = content[:content.index(end)]
            return content
        
    def export(self, title, words):
        url = 'http://quizlet.com/create_set/'
        params = {}
        #
        params['v'] = 8
        params['ajax'] = 1
        params['term_count'] = len(words)
        params['qnonce'] = self.getQnonce()
        #
        params['title'] = title.encode('utf-8')
        params['description'] = self.template['description']
        params['tags'] = self.template['tags']
        #
        params['disscussion'] = 1
        params['accessible_by'] = 'public'
        params['editable_by'] = 'only_me'
        params['create_set_password'] = ''
        #
        params['item_delimiter'] = 'tab'
        params['item_custom'] = ' - '
        params['term_delimiter'] = 'newline'
        params['term_custom'] = '\n\n'
        params['text'] = ''
        #
        params['words_lang'] = self.template['words_lang']
        params['defs_lang'] = self.template['defs_lang']
        #
        params['last_input'] = 1
        params['newUser'] = 0
        params['parent_id'] = 0
        postdata = urllib.urlencode(params)
        #
        for word in words:
            term = {}
            term['terms[]'] = word[self.col_term].encode('utf-8');
            term['defs[]'] = word[self.col_def].encode('utf-8');
            term['termIDs[]'] = 0;
            term['photos[]'] = '';
            termdata = '&' + urllib.urlencode(term)
            postdata += termdata
        #print "postdata length %d :" % len(postdata)
        try:
            response = urllib2.urlopen(url, postdata)
            if response.getcode() == 200 :
                return True
        except Exception as e:
            if isinstance(e, urllib2.HTTPError):
                print e.code
                print e.hdrs
                print e.message
                print e.msg
                print e.fp
            else:
                print e
            return False
            #raise e


if __name__ == '__main__' :
    d = QuizletDumper()
    while d.delete('Oxford 3000'): None
##    response = d.login()
##    for header in response.headers.headers:
##        print header.strip()
##    q = d.getQnonce()
##    print q
    #print 'end'
